<template>
  <div class="videoInfo-container">
    <!-- 视频信息 -->
    <div class="infoTop card-shadow">
      <div class="info">
        <div class="cover">
          <el-image :src="info?.cover" fit="cover">
            <template #placeholder> 暂无封面 </template>
            <template #error> 封面获取失败 </template>
          </el-image>
          <input type="file" id="file-input" accept=".jpg,.jpeg,.png" style="display: none" />
          <div class="upload-cover" @click.stop="toSelectCover">上传封面</div>
        </div>
        <div class="desc">
          <h2>{{ info?.title }}</h2>
          <p><span class="h">总集数: </span>{{ info?.totalPart }}</p>
          <p><span class="h">演员: </span>{{ info?.performers }}</p>
          <p><span class="h">创建时间: </span>{{ info?.createTime.slice(0, 10) }}</p>
          <p><span class="h">更新时间: </span>{{ info?.updateTime.slice(0, 10) }}</p>
          <p><span class="h">简介: </span>{{ info?.desc }}</p>
        </div>
      </div>
    </div>
    <!-- 剧集列表 -->
    <el-card style="margin-top: 24px">
      <template #header>
        <el-button plain size="small" @click="addPartDialog = true">新增剧集</el-button>
      </template>
      <el-table :data="parts" style="width: 100%">
        <el-table-column prop="sort" label="序号" width="100" />
        <el-table-column prop="title" label="标题" />
        <el-table-column
          prop="duration"
          :formatter="
            (row: VideoPart) => {
              return secondToMMss(row.duration)
            }
          "
          label="时长"
          width="180"
        />
        <el-table-column
          prop="createTime"
          :formatter="
            (row: VideoPart) => {
              return row.createTime.slice(0, 10)
            }
          "
          label="创建时间"
          width="180"
        />
        <el-table-column
          prop="updateTime"
          :formatter="
            (row: VideoPart) => {
              return row.updateTime.slice(0, 10)
            }
          "
          label="更新时间"
          width="180"
        />
        <el-table-column label="视频文件" width="100" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" size="small" plain @click.="previewFiles(row)"
              >查看文件</el-button
            >
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80" fixed="right">
          <template #default="{ row }">
            <el-button type="danger" icon="Delete" circle plain size="small" @click="preDel(row)" />
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 新增剧集对话框 -->
    <el-dialog v-model="addPartDialog" title="新增剧集" width="500">
      <!-- 表单 -->
      <el-form ref="addFormRef" :model="addForm" :rules="addFormRules" label-width="80px">
        <el-form-item label="标题" prop="title">
          <el-input placeholder="标题" :maxLength="20" v-model="addForm.title"></el-input>
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input placeholder="排序" :maxLength="20" v-model.number="addForm.sort"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="addPartDialog = false">取消</el-button>
          <el-button type="primary" @click="toAddPart(addFormRef)"> 提交 </el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 文件列表对话框 -->
    <el-dialog v-model="fileListDialog" title="文件列表" width="500">
      <!-- 文件上传 -->
      <el-upload
        ref="uploadRef"
        action="#"
        :auto-upload="false"
        :on-change="handleFileChange"
        :show-file-list="false"
        accept=".mp4,.avi,.mkv"
      >
        <el-button type="primary">选择文件</el-button>
        <template #tip>
          <div class="el-upload__tip">
            支持多选,文件类型为.mp4 , .avi 或 .mkv。<template v-if="selectFiles?.length! > 0"
              >已选择{{ selectFiles?.length }}个文件。<el-button
                link
                @click="clearFiles"
                size="small"
                type="primary"
                >清空
              </el-button></template
            >
          </div>
        </template>
      </el-upload>
      <!-- 文件列表 -->
      <div
        v-if="!fileAppending"
        class="iScroll"
        style="max-height: 45vh; width: 100%; overflow-y: scroll"
      >
        <p v-for="item in fileNames" :key="item">
          {{ item }}
          <el-button
            icon="Close"
            circle
            size="small"
            link
            @click="deleteOneFile(item, currentPartId)"
          />
        </p>
      </div>
      <!-- 文件选择列表 -->
      <div v-else class="iScroll" style="max-height: 45vh; width: 100%; overflow-y: scroll">
        <div v-for="(item, index) in selectFiles" :key="item?.uid">
          <text style="font-weight: 600">文件名:</text> {{ item?.name }}
          <el-button icon="Close" circle @click="removeFile(index, item!)" size="small" link />
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer" v-if="!fileAppending">
          <el-button type="primary" @click="deleteAllFile(currentPartId)"> 清空文件 </el-button>
        </div>
        <div class="dialog-footer" v-if="fileAppending">
          <el-button @click="clearFiles">取消</el-button>
          <el-button
            type="primary"
            @click="toUpload(currentPartId, selectFiles as UploadRawFile[])"
          >
            提交
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { secondToMMss } from '@/utils/format'
import {
  getVideoInfo,
  getVideoParts,
  deleteVideoParts,
  getVideoPartsFilesList,
  addPart,
  uploadPartFile,
  clearPartFile,
  deletePartFile,
  uploadCover
} from '@/api/video/manage'
import { type Action } from 'element-plus'
import { debounce } from '@/utils/throttleAndDebounce'

const route = useRoute()

const videoId = ref<number>(0)
const info = ref<Videos>()

// 集数
const parts = ref<VideoPart[]>()

// 获取剧集列表
function toGetVideoParts() {
  getVideoParts(videoId.value).then((res) => {
    parts.value = res.data
  })
}

let fileInput: HTMLInputElement

onMounted(() => {
  videoId.value = Number(route.query.videoId) ?? 0
  getVideoInfo(videoId.value).then((res) => {
    info.value = res.data
  })
  toGetVideoParts()

  fileInput = document.getElementById('file-input') as HTMLInputElement
  fileInput.addEventListener(
    'change',
    debounce(async function (e: Event) {
      const input = e.target as HTMLInputElement
      const files = input.files
      if (files && files.length === 1) {
        // 确保只处理一个文件
        const filesArr = fileInput.files ? Array.from(fileInput.files) : []
        console.log(filesArr)

        await uploadCover(videoId.value, filesArr)
        getVideoInfo(videoId.value).then((res) => {
          info.value = res.data
        })
      }
    }, 1000)
  )
})

// 点击上传封面
function toSelectCover() {
  fileInput.value = ''
  fileInput.click()
}

// 确认删除
function preDel(row: VideoPart) {
  ElMessageBox.alert('此操作将删除本条数据,及其对应的视频文件', '确认删除', {
    autofocus: false,
    showCancelButton: true,
    type: 'error',
    callback: (action: Action) => {
      if (action === 'confirm') {
        deleteVideoParts(row.id).then((res) => {
          if (res.code === 200) {
            ElMessage({
              type: 'success',
              message: '删除成功'
            })
            toGetVideoParts()
          }
        })
      }
    }
  })
}

// 新增对话框开关
const addPartDialog = ref(false)
// 表单
const addFormRef = ref<FormInstance>()
// 表单数据
const addForm = ref({
  title: '',
  sort: 0
})
const addFormRules = reactive<FormRules<typeof addForm>>({
  title: { required: true, message: '请填写标题' },
  sort: [
    { type: 'number', min: 1, trigger: ['change', 'blur'], message: '需要数值且大于0' },
    { required: true, message: '请填写排序' }
  ]
})
// 提交表单
function toAddPart(formR: FormInstance | undefined) {
  if (!formR) return
  formR.validate((vaild: boolean) => {
    if (vaild) {
      videoId.value = Number(route.query.videoId) ?? 0
      addPart({ ...addForm.value, videoId: videoId.value } as VideoPart).then((res) => {
        if (res.code === 200) {
          ElMessage({
            type: 'success',
            message: '新增成功'
          })
          toGetVideoParts()
          addPartDialog.value = false
        }
      })
    }
  })
}

// 文件列表对话框
const fileListDialog = ref(false)
// 文件名集合
const fileNames = ref<string[]>()

const currentPartId = ref(0)
// 查看文件列表
function previewFiles(row: VideoPart) {
  fileListDialog.value = true
  currentPartId.value = row.id
  getVideoPartsFilesList(currentPartId.value).then((res) => {
    if (res.code === 200) {
      fileNames.value = res.data
    }
  })
}

// 删除单个文件
function deleteOneFile(name: string, partId: number) {
  deletePartFile(partId, name).then((res) => {
    if (res.code === 200) {
      ElMessage({
        type: 'success',
        message: '删除成功'
      })
      getVideoPartsFilesList(currentPartId.value).then((res) => {
        if (res.code === 200) {
          fileNames.value = res.data
        }
      })
    }
  })
}

// 删除所有文件
function deleteAllFile(partId: number) {
  clearPartFile(partId).then((res) => {
    if (res.code === 200) {
      ElMessage({
        type: 'success',
        message: '清空成功'
      })
      getVideoPartsFilesList(currentPartId.value).then((res) => {
        if (res.code === 200) {
          fileNames.value = res.data
        }
      })
    }
  })
}

// 文件添加中
const fileAppending = ref(false)
// 上传组件
const uploadRef = ref<UploadInstance>()
// 已选择的文件
const selectFiles = ref<UploadRawFile[]>()

// 文件变化
function handleFileChange(file: UploadFile, fileList: UploadFiles) {
  fileAppending.value = fileList.length > 0
  console.log(file)
  console.log(fileList)
  selectFiles.value = [...fileList.map((item) => item.raw)] as UploadRawFile[]
}

// 清空选择的文件
function clearFiles() {
  uploadRef.value?.clearFiles()
  selectFiles.value = []
  fileAppending.value = false
}

// 移除单个文件
function removeFile(index: number, file: UploadRawFile) {
  uploadRef.value?.handleRemove(file)
  selectFiles.value?.splice(index, 1)
  fileAppending.value = selectFiles.value!.length > 0
}

// 手动上传文件
async function toUpload(partId: number, files: UploadRawFile[]) {
  const loading = ElLoading.service({
    lock: true,
    text: '上传并转码中, 请等待',
    background: 'rgba(0, 0, 0, 0.7)'
  })
  await uploadPartFile(partId, files)
  clearFiles()
  getVideoPartsFilesList(currentPartId.value).then((res) => {
    if (res.code === 200) {
      fileNames.value = res.data
    }
  })
  loading.close()
}
</script>

<style lang="scss" scoped>
.videoInfo-container {
  width: 100%;
  height: 100%;
  .infoTop {
    width: calc(100% - 48px);
    padding: 24px;
    .info {
      display: flex;
      gap: 26px;
      h2 {
        margin: 0;
      }
      .cover {
        position: relative;
        width: 30%;
        min-width: 200px;
        max-width: 250px;
        max-height: max-content;
        :deep(.el-image) {
          aspect-ratio: 3 / 4;
          width: 100%;
          height: auto;
          padding: 0;
          margin: 0;
        }
        .upload-cover {
          width: 100%;
          height: 40px;
          position: absolute;
          bottom: 5px;
          background-color: rgba(0, 0, 0, 0.2);
          color: white;
          font-size: 0.7em;
          display: flex;
          justify-content: center;
          align-items: center;
          margin: 0;
          padding: 0;
          &:hover {
            background-color: rgba(0, 0, 0, 0.6);
            font-weight: 600;
            cursor: pointer;
          }
        }
      }
      .desc {
        .h {
          font-size: 0.9em;
          font-weight: 600;
          margin-right: 6px;
        }
      }
    }
  }
}
</style>
